/*
 * a7106.h
 *
 *  Created on: 2023年11月1日
 *      Author: y-7
 */

#ifndef INCLUDE_A7106_H_
#define INCLUDE_A7106_H_

#include <esp_log.h>

 
/// A7105 states for strobe
typedef enum {
    A7105_STROBE_MATCH_CH = 0x01,   // 对码通道
    A7105_STROBE_DATA_CH = 0x02,    // 数据通道
    A7105_STROBE_UPDATE_CH = 0x03,  // 更新通道
    A7105_STROBE_CHANGE = 0x08,     // 切换
    //------------------------------
    A7105_STROBE_SLEEP = 0x80,
    A7105_STROBE_IDLE = 0x90,
    A7105_STROBE_STANDBY = 0xA0,
    A7105_STROBE_PLL = 0xB0,
    A7105_STROBE_RX = 0xC0,
    A7105_STROBE_TX = 0xD0,
    A7105_STROBE_RST_WRPTR = 0xE0,
    A7105_STROBE_RST_RDPTR = 0xF0,
} a7106_strobe_t;


/// Register addresses
typedef enum {
    A7105_00_MODE = 0x00,
    A7105_01_MODE_CONTROL = 0x01,
    A7105_02_CALC = 0x02,
    A7105_03_FIFO_I = 0x03,
    A7105_04_FIFO_II = 0x04,
    A7105_05_FIFO_DATA = 0x05,
    A7105_06_ID_DATA = 0x06,
    A7105_07_RC_OSC_I = 0x07,
    A7105_08_RC_OSC_II = 0x08,
    A7105_09_RC_OSC_III = 0x09,
    A7105_0A_CK0_PIN = 0x0A,
    A7105_0B_GPIO1_PIN_I = 0x0B,
    A7105_0C_GPIO2_PIN_II = 0x0C,
    A7105_0D_CLOCK = 0x0D,
    A7105_0E_DATA_RATE = 0x0E,
    A7105_0F_PLL_I = 0x0F,              ///< CHN [7:0]: LO channel number select.
    A7105_10_PLL_II = 0x10,
    A7105_11_PLL_III = 0x11,
    A7105_12_PLL_IV = 0x12,
    A7105_13_PLL_V = 0x13,
    A7105_14_TX_I = 0x14,
    A7105_15_TX_II = 0x15,
    A7105_16_DELAY_I = 0x16,
    A7105_17_DELAY_II = 0x17,
    A7105_18_RX = 0x18,
    A7105_19_RX_GAIN_I = 0x19,          /// RX Gain Register I
    A7105_1A_RX_GAIN_II = 0x1A,         /// RX Gain Register II
    A7105_1B_RX_GAIN_III = 0x1B,        /// RX Gain Register III
    A7105_1C_RX_GAIN_IV = 0x1C,         /// RX Gain Register IV
    A7105_1D_RSSI_THOLD = 0x1D,
    A7105_1E_ADC = 0x1E,
    A7105_1F_CODE_I = 0x1F,
    A7105_20_CODE_II = 0x20,
    A7105_21_CODE_III = 0x21,
    A7105_22_IF_CALIB_I = 0x22,
    A7105_23_IF_CALIB_II = 0x23,
    A7105_24_VCO_CURCAL = 0x24,
    A7105_25_VCO_SBCAL_I = 0x25,
    A7105_26_VCO_SBCAL_II = 0x26,
    A7105_27_BATTERY_DET = 0x27,
    A7105_28_TX_TEST = 0x28,
    A7105_29_RX_DEM_TEST_I = 0x29,
    A7105_2A_RX_DEM_TEST_II = 0x2A,
    A7105_2B_CPC = 0x2B,
    A7105_2C_XTAL_TEST = 0x2C,
    A7105_2D_PLL_TEST = 0x2D,
    A7105_2E_VCO_TEST_I = 0x2E,
    A7105_2F_VCO_TEST_II = 0x2F,
    A7105_30_IFAT = 0x30,
    A7105_31_RSCALE = 0x31,
    A7105_32_FILTER_TEST = 0x32,
} a7106_register_addr_t;

/// Power amp is ~+16dBm so:
typedef enum {
    TXPOWER_100uW,  // -23dBm == PAC=0 TBG=0
    TXPOWER_300uW,  // -20dBm == PAC=0 TBG=1
    TXPOWER_1mW,    // -16dBm == PAC=0 TBG=2
    TXPOWER_3mW,    // -11dBm == PAC=0 TBG=4
    TXPOWER_10mW,   // -6dBm  == PAC=1 TBG=5
    TXPOWER_30mW,   // 0dBm   == PAC=2 TBG=7
    TXPOWER_100mW,  // 1dBm   == PAC=3 TBG=7
    TXPOWER_150mW,  // 1dBm   == PAC=3 TBG=7
    TXPOWER_LAST,
} tx_power_t;


/// TX/RX state
typedef enum {
    TXRX_OFF,
    TX_EN,
    RX_EN,
} txrx_state_t;

//Bit operations
#define A7105_WRITE(a)    ((a) & ~0x40)
#define A7105_READ(a)     ((a) | 0x40)
#define A7105_SET_BIT(byte, bit) ((byte) |= ((1) << (bit)))
#define A7105_CLEAR_BIT(byte, bit) ((byte) &= ~((1) << (bit)))
#define A7105_TOGGLE_BIT(byte, bit) ((byte) ^= ((1) << (bit)))
#define A7105_TEST_BIT(byte, bit) (((byte) >> (bit)) & (1))    //returns 1 or 0


typedef enum A7105_MASK {
    A7105_MASK_FBCF = 1 << 4,
    A7105_MASK_VBCF = 1 << 3,
} A7105_MASK;

#define ID_CODE0 0x54
#define ID_CODE1 0x75
#define ID_CODE2 0xc5
#define ID_CODE3 0x2a
#define A7105_ID_CFIG   0x2ac57554   // 配对ID值|不能修改！
#define A7105_CH_CFIG   0X63         // 配对通道|不能修改！
//#define A7105_ID_CODE   0x4d9b4d9b  // 4d 9b 9b 4d 
//#define A7105_CHANNLE   0X4d   //

#define RF_FIFO_LEN     4

typedef union {
    uint8_t  u8[4];
    uint16_t u16[2];
    uint32_t u32;
} __attribute__((aligned(4))) a7106_id_t;

void a7106_set_channel(uint8_t channel);
void a7106_write_strobe(a7106_strobe_t strobe);

void a7106_write_id(a7106_id_t id);
void a7106_read_id(a7106_id_t *id);

a7106_strobe_t a7106_write_data(const uint8_t *data, uint8_t len);
uint8_t a7106_read_data(uint8_t *data, uint8_t len);

void hal_a7106_init(void);

//==============================================================================================
//==============================================================================================
// RF遥控器指令！
#define RF_MOTOR_MODE_CASUAL     {0x55,0x55,0xee,0xee}        // 休闲模式
#define RF_MOTOR_MODE_SLEEP      {0xaa,0xaa,0x33,0x33}        // 深睡模式
#define RF_MOTOR_MODE_TV         {0x66,0x66,0xdd,0xdd}        // TV模式
#define RF_MOTOR_MODE_READ       {0xaa,0xaa,0x11,0x11}        // 阅读模式
#define RF_MOTOR_MODE_ZERO       {0x99,0x99,0x99,0x99}        // 零压模式
#define RF_MOTOR_MODE_SNORE      {0x99,0x99,0xaa,0xaa}        // 止鼾模式
#define RF_MOTOR_NULL            {0x00,0x00,0x00,0x00}        // 空
#define RF_MOTOR_BACK_UP         {0x55,0x55,0x44,0x44}        // 背升
#define RF_MOTOR_BACK_DOWN       {0x55,0x55,0x55,0x55}        // 背降
#define RF_MOTOR_LEG_UP          {0x55,0x55,0x66,0x66}        // 腿升
#define RF_MOTOR_LEG_DOWN        {0x55,0x55,0x77,0x77}        // 腿降
#define RF_MOTOR_ALL_UP          {0x55,0x55,0x99,0x99}        // 同升
#define RF_MOTOR_ALL_DOWN        {0x55,0x55,0xaa,0xaa}        // 同降

void motor_set_mode(uint8_t index);
void motor_set_angle(uint8_t index);

#endif /* INCLUDE_A7106_H_ */
